
`ifndef XPIP_RTL_PKG
`define XPIP_RTL_PKG

package xpip_rtl_pkg;

parameter int WORD_BYTES         = 4,
              HALF_BYTES         = WORD_BYTES / 2,
              WORD_BITS          = WORD_BYTES * 8,
              DWORD_BITS         = WORD_BITS * 2,
              HALF_BITS          = HALF_BYTES * 8;
                
typedef logic [HALF_BYTES - 1 : 0][7:0] halfb;
typedef logic [HALF_BITS - 1: 0] half;
typedef logic [WORD_BYTES - 1 : 0][7:0] wordb;
typedef logic [WORD_BITS - 1: 0] word;
typedef logic [DWORD_BITS - 1 : 0] dword;
typedef logic [1:0][HALF_BITS - 1: 0] wordh;
typedef logic [7:0] byt;

typedef union packed unsigned{
  logic [HALF_BYTES - 1 : 0][7:0] b;
  logic [HALF_BITS - 1: 0] h;
} halfu;

typedef union packed unsigned{
  logic [WORD_BYTES - 1 : 0][7:0] b;
  logic [WORD_BITS - 1: 0] w;
  halfu [1:0] h;
} wordu;

///Basic functions for parameters etc
  
function automatic bit[63:0] clogb2(
  input bit[63:0] value
);
  bit[63:0] v;
  clogb2 = 0;
  for (v = value; v > 0; clogb2 = clogb2 + 1)
    v = v >> 1;
endfunction

function automatic bit[63:0] n2w(
  input bit[63:0] value
);
  n2w = clogb2(value);
  if(n2w > 0)
    n2w--;
endfunction
  
function automatic bit[63:0] max2(
  input bit[63:0] a0, a1
);
  max2 = a0;
  if (a0 < a1)
    max2 = a1;
endfunction

function automatic bit[63:0] min2(
  input bit[63:0] a0, a1
);
  min2 = a0;
  if (a0 > a1)
    min2 = a1;
endfunction

parameter int WID_EX_ADDR    = 32,
              WID_AXI_ID     = 4,
              MCV            = 4,
              DP_VRF_BK      = 0,
              DP_OCM_BK      = 0;

parameter int  NUM_SP            = 8,
               NUM_VEC           = NUM_SP * MCV,
               NUM_SFU           = NUM_SP,
               NUM_THRD          = 8,
               NUM_LANE          = 2,
               NUM_THREAD        = NUM_THRD * NUM_LANE,
               NUM_FU            = 3,
               NUM_VRF_BKS       = 4,
               NUM_SRF_BKS       = 2,
               NUM_EXUS          = 1,
               NUM_THRD_GRP      = 4,
               NUM_SMTLB_TGRP    = 2,
               NUM_IFET_BYTES    = 16,
               NUM_INST_BUF      = 8,
               NUM_ISU_OCNT      = 4,
               NUM_BR_HISTORY    = 32,
               NUM_FCR_RET       = 8;
               
parameter int  NUM_LSV_RBUF      = 32,
               NUM_LSV_SBUF      = 32,
               NUM_LSV_LTB0      = 8,
               NUM_LSV_STB0      = 16,
               NUM_LSV_LTB1      = 8,
               NUM_LSV_STB1      = 8,
               NUM_LSV_STB2      = 8,
               NUM_LSS_RBUF      = 32;
                
parameter int  NUM_SMEM_PAR      = 4,
               NUM_SMEM_PAR_W    = 512,
               NUM_SMEM_BK       = 16,  ///must in range [NUM_SP, NUM_VEC]
               NUM_DCHE_CL       = 2,   ///NUM_DCHE_CL * NUM_SMEM_BK >= NUM_VEC
               NUM_DCHE_ASO      = 4,
               NUM_DCHE_ENT      = NUM_SMEM_PAR_W / (NUM_DCHE_CL * NUM_DCHE_ASO),
               NUM_DCU_RIB       = 8,
               NUM_DCU_DIB       = 4,
               NUM_DCU_EWB       = 8,
               NUM_DCU_SDB       = 16,
               NUM_DCU_RDB       = 8,
               NUM_DCU_ASB       = 4,
               NUM_DCU_ERB       = 16,
               NUM_DCU_RWB       = 16,
               NUM_DCU_ORB       = 16,
               NUM_DCU_RRB       = 8,
               NUM_DCU_ERIB      = 16,
               NUM_DCU_EDIB      = 4;

parameter int LAT_MAC           = 7,
              LAT_SFU           = 16,
              LAT_RF            = 1,
              LAT_RBP           = 1,
              LAT_VWBP          = 1,    ///vector writeback bypass time
              LAT_WB            = 4,
              LAT_ISE           = 2,
              LAT_IFE           = 2,
              LAT_L1M           = 1,
              LAT_SEL           = 1,
              LAT_SWBP          = 1;    ///dse writeback bypass time
                              
parameter int WID_VRF_ADR     = n2w(NUM_THRD * 32 / NUM_VRF_BKS),
              WID_SRF_ADR     = n2w(NUM_THRD * 32 / NUM_SRF_BKS),
              WID_WORD        = n2w(WORD_BYTES),
              WID_HALF        = n2w(HALF_BYTES),
              WID_VRF_BKS     = n2w(NUM_VRF_BKS),
              WID_SRF_BKS     = n2w(NUM_SRF_BKS),
              WID_LTID        = n2w(NUM_THRD),
              WID_LANE        = n2w(NUM_LANE),
              WID_TID         = n2w(NUM_THREAD),
              WID_VID         = n2w(NUM_VEC),
              WID_INST_BUF    = n2w(NUM_INST_BUF),
              WID_SP          = n2w(NUM_SP),
              WID_VEC         = n2w(MCV),
              WID_HVEC        = WID_VEC - 1,
              WID_THRD_GRP    = n2w(NUM_THRD_GRP),
              WID_IFET        = n2w(NUM_IFET_BYTES),
              WID_RF_ADR      = max2(WID_VRF_ADR, WID_SRF_ADR),
              WID_RF_BK       = n2w(max2(NUM_VRF_BKS, NUM_SRF_BKS)),
              WID_SMTLB_TGRP  = n2w(NUM_SMTLB_TGRP),
              WID_ISU_OCNT    = n2w(NUM_ISU_OCNT),
              WID_EX_DATA     = max2(NUM_SMEM_BK * NUM_DCHE_CL * WORD_BITS / 16, 128),///limited by ace
              BYTES_EX_DATA   = WID_EX_DATA / 8;

typedef logic[WID_SP - 1:0] spid_t;
typedef logic[WID_VEC - 1:0] cyc_t;
typedef logic[WID_HVEC - 1:0] hcyc_t;
typedef logic[WID_TID - 1:0] tid_t;
typedef logic[WID_LTID - 1:0] ltid_t;
typedef logic[WID_LANE - 1:0] lid_t;

/*
                                           pipeline stages:
ise,ife:      | ife0 | ife1 | ib/pred | isu0 | isu1/isu2 |

                                           pipeline stages:
                                          
vector:   | rrf  | rrc0 | rrc1 | rrc2 | rrc3 | exe0 | exe1 | exe2 | exe3 | exe4 | exe5 | exe6 |  vwb |
vload:    | rrf  | rrc0 | rrc1 | rrc2 | rrc3 |  ag  |  sel |  ad0 | ad1  | ad2  | ad3  | dc0  | dc1  | lxg0 | lxg1 | lxg2 | lxg3 | vwb |
vstore:   | rrf  | rrc0 | rrc1 | rrc2 | rrc3 |  ag  |  sel | sxg0 | sxg1 | sxg2 | sxg3 | dc0  | dc1  |
cmp/fcmp: | rrf  | rrc0 | rrc1 | rrc2 | rrc3 | cmp0 | cmp1 | cmp2 | cmp3 | swb  |
scalar:   | rrf  | rrc0 | exs0 | exs1 | exs2 | exs3 | exs4 | exs5 | exs6 | swb  |

          0      1      2      3      4      5      6      7      8      9      10     11     12     13     14     15
                                             0      1      2      3      4      5      6      7      8      9      10
                        0      1      2      3      4      5      6    
  */

parameter int SG_RRF_SWB	    = LAT_RF + LAT_RBP + LAT_MAC,        ///9
              SG_BR_RSP       = LAT_RF + LAT_RBP + 1;

                
/*
typedef logic[7:0] sradr_t;
typedef logic[7:0] mradr_t;

typedef logic[7:0] exp_t;
typedef enum int {
  exp_zero,   exp_inf,    exp_inv,    exp_tiny,
  exp_huge,   exp_inex,   exp_ovfl,   exp_div0
} exp_bit_e;

typedef enum logic[2:0] {
  rnd_even,     rnd_zero,     rnd_posi,     rnd_negi,     rnd_up,     rnd_away
}round_mode_t;

typedef enum logic[5:0] {
  SR_PROC_CTL,  SR_SUPMSG,    SR_EBASE,     SR_MBASE,       SR_INDEX,
  SR_RANDOM,    SR_ENTRY_L0,  SR_ENTRY_L1,  SR_ENTRY_AT,    SR_ENTRY_HI,
  SR_TIMER,     SR_CMP,       SR_OCMC,      SR_PCNT[0:1],   SR_PCNTC[0:1],
  SR_IIDX,      SR_IIDY,      SR_IIDZ,      SR_EXPFV,       SR_DSEEV,
  SR_MSCO,      SR_MSCU,      SR_THD_CTL,   SR_THD_ST,      SR_EXEC,
  SR_CONTENT,   SR_EPC,       SR_ERET,      SR_WIDX,        SR_WIDY,
  SR_WIDZ,      SR_ILM,       SR_CM,        SR_UEE,         SR_UER,
  SR_ASID,      SR_MD[0:7],   SR_MCS[0:2],  SR_FFS,         SR_FFC[0:1],
  SR_SUPM[0:1]
}special_reg_t;

parameter special_reg_t tlb_sr[6] = '{
  SR_INDEX,     SR_RANDOM,    SR_ENTRY_L0,    SR_ENTRY_L1,
  SR_ENTRY_HI,  SR_ASID
};

parameter special_reg_t non_kernel_sr[3] = '{
  SR_EXEC,     SR_UEE,       SR_UER
};

typedef enum logic[3:0] {
  EC_NOEXP,     EC_TLBIFET,   EC_NOTEXE,    EC_EXEPRIV,
  EC_DECODE,    EC_SYSCAL,    EC_BREAK,     EC_SUPMSG,
  EC_IFACC,     EC_LSACC,     EC_SCLFU,     EC_MSC,
  EC_TIMER,     EC_PCNT[0:1]
}cause_spu_t;

typedef enum logic[2:0] {
  EC_NODSE,     EC_TLBINV,    EC_TLBMOD,    EC_TLBPRIV,
  EC_ADRALG,    EC_SMBOND
}cause_dse_t;

typedef enum logic[WID_PADR - 1:0] {
  UE_FFCLN = 'h0,
  UE_FFREV = 'h40,
  UE_FFRTG = 'h50,
  UE_FFSTG = 'h60,
  UE_FFRFL = 'h70,
  UE_FFSFL = 'h80,
  UE_FFSYN = 'h90
}user_event_os_t;

*/

`include "inst.svh"
`include "biu.svh"
`include "isu.svh"
`include "lsu.svh"
`include "dcu.svh"

typedef struct{
  vpn_t smVpn[NUM_THRD_GRP][NUM_SMTLB_TGRP];
  page_typ_e smTyp[NUM_THRD_GRP][NUM_SMTLB_TGRP];
  par_t ocm; ///mask for par e.g. 00 01 11
} core_cfg_inf_s;
  
parameter core_cfg_inf_s core_cfg_inf_def = '{
  smVpn     : '{default : '0},
  smTyp     : '{default : page_min},
  default   : '0
};

endpackage : xpip_rtl_pkg

`endif